package com.ruoyi.datastatistics.service.impl;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import cn.hutool.core.date.DateUtil;
import com.ruoyi.basedata.domain.*;
import com.ruoyi.basedata.mapper.ElectricityAreaZoneJoinMapper;
import com.ruoyi.basedata.mapper.ElectricityTerminalsXbMapper;
import com.ruoyi.basedata.service.IMeterSheetsService;
import com.ruoyi.datastatistics.domain.TerminalsFreezeXb;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.datastatistics.mapper.ElectricityTerminalsFreezeXbMapper;
import com.ruoyi.datastatistics.domain.ElectricityTerminalsFreezeXb;
import com.ruoyi.datastatistics.service.IElectricityTerminalsFreezeXbService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.transaction.annotation.Transactional;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
/**
 * 电冻结数据（设备维度）Service业务层处理
 *
 * @author gdqt
 * @date 2025-03-10
 */
@Service
public class ElectricityTerminalsFreezeXbServiceImpl extends ServiceImpl<ElectricityTerminalsFreezeXbMapper, ElectricityTerminalsFreezeXb> implements IElectricityTerminalsFreezeXbService
{
    @Autowired
    private ElectricityTerminalsFreezeXbMapper electricityTerminalsFreezeXbMapper;

    @Autowired
    private IMeterSheetsService meterSheetsService;

    @Autowired
    private ElectricityAreaZoneJoinMapper electricityAreaZoneJoinMapper;

    @Autowired
    private ElectricityTerminalsXbMapper electricityTerminalsXbMapper;

    /**
     * 查询电冻结数据（设备维度）
     *
     * @param id 电冻结数据（设备维度）主键
     * @return 电冻结数据（设备维度）
     */
    @Override
    public ElectricityTerminalsFreezeXb selectElectricityTerminalsFreezeXbById(Long id)
    {

        return electricityTerminalsFreezeXbMapper.selectById(id);
    }


    /**
     * 查询电-日月报数据列表
     *
     * @param electricityTerminalsFreezeXb 电-日月报数据
     * @return 电-日月报数据
     */
    @Override
    public List<ElectricityTerminalsFreezeXb> selectElectricityTerminalsFreezeXbList(ElectricityTerminalsFreezeXb electricityTerminalsFreezeXb)
    {
        LambdaQueryWrapper<ElectricityTerminalsFreezeXb> queryWrapper = new LambdaQueryWrapper<>();
        if(!StringUtils.isEmpty(electricityTerminalsFreezeXb.getTenantId())){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getTenantId,electricityTerminalsFreezeXb.getTenantId());
        }
        if(!StringUtils.isEmpty(electricityTerminalsFreezeXb.getLocationNb())){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getLocationNb,electricityTerminalsFreezeXb.getLocationNb());
        }
        if(!StringUtils.isEmpty(electricityTerminalsFreezeXb.getSupplierId())){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getSupplierId,electricityTerminalsFreezeXb.getSupplierId());
        }
        if(!StringUtils.isEmpty(electricityTerminalsFreezeXb.getTerminalId())){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getTerminalId,electricityTerminalsFreezeXb.getTerminalId());
        }
        if(electricityTerminalsFreezeXb.getStartPositiveActiveEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getStartPositiveActiveEnergy,electricityTerminalsFreezeXb.getStartPositiveActiveEnergy());
        }
        if(electricityTerminalsFreezeXb.getEndPositiveActiveEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getEndPositiveActiveEnergy,electricityTerminalsFreezeXb.getEndPositiveActiveEnergy());
        }
        if(electricityTerminalsFreezeXb.getStartReverseActiveEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getStartReverseActiveEnergy,electricityTerminalsFreezeXb.getStartReverseActiveEnergy());
        }
        if(electricityTerminalsFreezeXb.getEndReverseActiveEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getEndReverseActiveEnergy,electricityTerminalsFreezeXb.getEndReverseActiveEnergy());
        }
        if(electricityTerminalsFreezeXb.getDosagePositiveActiveEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosagePositiveActiveEnergy,electricityTerminalsFreezeXb.getDosagePositiveActiveEnergy());
        }
        if(electricityTerminalsFreezeXb.getDosageReverseActiveEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageReverseActiveEnergy,electricityTerminalsFreezeXb.getDosageReverseActiveEnergy());
        }
        if(electricityTerminalsFreezeXb.getDosageCombinationActiveEnergy1() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageCombinationActiveEnergy1,electricityTerminalsFreezeXb.getDosageCombinationActiveEnergy1());
        }
        if(electricityTerminalsFreezeXb.getDosageCombinationActiveEnergy2() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageCombinationActiveEnergy2,electricityTerminalsFreezeXb.getDosageCombinationActiveEnergy2());
        }
        if(electricityTerminalsFreezeXb.getDosageCombinationIdleEnergy1() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageCombinationIdleEnergy1,electricityTerminalsFreezeXb.getDosageCombinationIdleEnergy1());
        }
        if(electricityTerminalsFreezeXb.getDosageCombinationIdleEnergy2() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageCombinationIdleEnergy2,electricityTerminalsFreezeXb.getDosageCombinationIdleEnergy2());
        }
        if(electricityTerminalsFreezeXb.getDosageFirstIdleEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageFirstIdleEnergy,electricityTerminalsFreezeXb.getDosageFirstIdleEnergy());
        }
        if(electricityTerminalsFreezeXb.getDosageSecondIdleEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageSecondIdleEnergy,electricityTerminalsFreezeXb.getDosageSecondIdleEnergy());
        }
        if(electricityTerminalsFreezeXb.getDosageThirdIdleEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageThirdIdleEnergy,electricityTerminalsFreezeXb.getDosageThirdIdleEnergy());
        }
        if(electricityTerminalsFreezeXb.getDosageFourthIdleEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageFourthIdleEnergy,electricityTerminalsFreezeXb.getDosageFourthIdleEnergy());
        }
        if(electricityTerminalsFreezeXb.getDosageAPositiveActiveEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageAPositiveActiveEnergy,electricityTerminalsFreezeXb.getDosageAPositiveActiveEnergy());
        }
        if(electricityTerminalsFreezeXb.getDosageBPositiveActiveEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageBPositiveActiveEnergy,electricityTerminalsFreezeXb.getDosageBPositiveActiveEnergy());
        }
        if(electricityTerminalsFreezeXb.getDosageCPositiveActiveEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageCPositiveActiveEnergy,electricityTerminalsFreezeXb.getDosageCPositiveActiveEnergy());
        }
        if(electricityTerminalsFreezeXb.getDosageDPositiveActiveEnergy() != null){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getDosageDPositiveActiveEnergy,electricityTerminalsFreezeXb.getDosageDPositiveActiveEnergy());
        }
        if(!StringUtils.isEmpty(electricityTerminalsFreezeXb.getFrozenType())){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getFrozenType,electricityTerminalsFreezeXb.getFrozenType());
        }
        if(!StringUtils.isEmpty(electricityTerminalsFreezeXb.getFreezeTime())){
            queryWrapper.eq(ElectricityTerminalsFreezeXb::getFreezeTime,electricityTerminalsFreezeXb.getFreezeTime());
        }
        return electricityTerminalsFreezeXbMapper.selectList(queryWrapper);
    }

    /**
     * 新增电冻结数据（设备维度）
     *
     * @param electricityTerminalsFreezeXb 电冻结数据（设备维度）
     * @return 结果
     */
    @Override
    public int insertElectricityTerminalsFreezeXb(ElectricityTerminalsFreezeXb electricityTerminalsFreezeXb)
    {
        return electricityTerminalsFreezeXbMapper.insert(electricityTerminalsFreezeXb);
    }

    /**
     * 修改电冻结数据（设备维度）
     *
     * @param electricityTerminalsFreezeXb 电冻结数据（设备维度）
     * @return 结果
     */
    @Override
    public int updateElectricityTerminalsFreezeXb(ElectricityTerminalsFreezeXb electricityTerminalsFreezeXb)
    {
        return electricityTerminalsFreezeXbMapper.updateById(electricityTerminalsFreezeXb);
    }

    /**
     * 批量删除电冻结数据（设备维度）
     *
     * @param ids 需要删除的电冻结数据（设备维度）主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteElectricityTerminalsFreezeXbByIds(Long[] ids)
    {
        return electricityTerminalsFreezeXbMapper.deleteBatchIds(Arrays.asList(ids));
    }

    /**
     * 删除电冻结数据（设备维度）信息
     *
     * @param id 电冻结数据（设备维度）主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteElectricityTerminalsFreezeXbById(Long id)
    {
        return electricityTerminalsFreezeXbMapper.deleteById(id);
    }

    /**
     * @Description: 能耗概况-电表用量前3数据
     * @date: 2025/3/14 14:22
     * @author: zt
     */
    @Override
    public Map<String, Object> getTopFlowList() {
        Map<String,Object> resMap = new HashMap<>();
        List<String> hourList = new ArrayList<>();
        for (int i = 0; i < 24; i++) {
            String tempHour = (i<10?"0"+i:""+i)+":00";
            hourList.add(tempHour);
        }
        resMap.put("hourList",hourList);
        //日期
        String todayDate = DateUtil.format(new Date(), "yyyy-MM-dd");
        String beforeDate1 = DateUtil.format(DateUtil.yesterday().toJdkDate(), "yyyy-MM-dd");
        String beforeDate2 = DateUtil.format(DateUtil.offsetDay(new Date(),-2), "yyyy-MM-dd");

        //用户绑定的区域
        List<MeterSheets> sheetsList = meterSheetsService.getAreaTree(1,null,null,
                null,null,false);
        //所有区域ID
//        List<Long> areaIds = recesiveAreaIds(sheetsList);
        //最下级
        List<MeterSheets> lastList = recursiveLast(sheetsList);
        List<Long> areaIds = lastList.stream().map(MeterSheets::getId).collect(Collectors.toList());
        //根据区域ID获取挂接的电表
        // List<ElectricityAreaZoneJoin> joinList = electricityAreaZoneJoinMapper.selectList(new LambdaQueryWrapper<ElectricityAreaZoneJoin>()
        //         .in(ElectricityAreaZoneJoin::getAreaId, areaIds));
        List<ElectricityTerminalsXb> joinList = electricityTerminalsXbMapper.selectList(new LambdaQueryWrapper<ElectricityTerminalsXb>()
                .in(ElectricityTerminalsXb::getSheetsId, areaIds).eq(ElectricityTerminalsXb::getDelFlag,0)
                .eq(ElectricityTerminalsXb::getTerminalMark, 1).groupBy(ElectricityTerminalsXb::getLocationNb)
                .select(ElectricityTerminalsXb::getId, ElectricityTerminalsXb::getLocationNb, ElectricityTerminalsXb::getInstallAddress));

        List<ElectricityTerminalsXb> terminalsXbList = electricityTerminalsXbMapper.selectList(new LambdaQueryWrapper<ElectricityTerminalsXb>()
                .eq(ElectricityTerminalsXb::getDelFlag,0).eq(ElectricityTerminalsXb::getTerminalMark,1));
        Map<String,List<ElectricityTerminalsXb>> locationNbTerminalMap = terminalsXbList.stream().collect(Collectors.groupingBy(ElectricityTerminalsXb::getLocationNb));

        //挂接表的locationNb数据
//        List<String> locationNbList = joinList.stream().map(ElectricityAreaZoneJoin::getLocationNb).filter(locationNb -> !com.ruoyi.common.utils.StringUtils.isEmpty(locationNb)).collect(Collectors.toList());
        Map<String,ElectricityTerminalsXb> locationNbMap = joinList.stream().filter(item ->
                        !com.ruoyi.common.utils.StringUtils.isEmpty(item.getLocationNb()))
                .collect(Collectors.toMap(ElectricityTerminalsXb::getLocationNb, Function.identity()));
        //查询时冻结数据
        if(!locationNbMap.isEmpty()){
            List<Map<String,Object>> yesterdayList = getYesterFreezeMap(locationNbMap,beforeDate1,hourList);
            if(!yesterdayList.isEmpty()){
                int size = Math.min(yesterdayList.size(), 3);
                for (int i = 0; i < size; i++) {
                    Map<String,Object> mm = new HashMap<>();
                    Map<String, Object> beforeMap1 = yesterdayList.get(i);
                    String locationNb = beforeMap1.get("locationNb").toString();

                    String terminalName = beforeMap1.get("terminalName") == null
                            ? (locationNbTerminalMap.get(locationNb)==null?"":locationNbTerminalMap.get(locationNb).get(0).getTerminalId())
                            : beforeMap1.get("terminalName").toString();

                    Map<String, Object> todayMap = getLocationNbFreezeMap(locationNb, todayDate, hourList);
                    Map<String, Object> beforeMap2 = getLocationNbFreezeMap(locationNb, beforeDate2, hourList);
                    mm.put("terminalName",terminalName);
                    mm.put("today",todayMap);
                    mm.put("before1",beforeMap1);
                    mm.put("before2",beforeMap2);
                    resMap.put("top"+(i+1),mm);
                }
            }
        }
        return resMap;
    }

    private Map<String,Object> getLocationNbFreezeMap(String locationNb,String date,List<String> hourList){
        String startDay = date + " 00:00:00";
        String endDay = date + " 23:59:59";
        //冻结小时数据
        List<ElectricityTerminalsFreezeXb> freezeXbList = this.getBaseMapper().selectList(new LambdaQueryWrapper<ElectricityTerminalsFreezeXb>()
                .eq(ElectricityTerminalsFreezeXb::getLocationNb,locationNb)
                .eq(ElectricityTerminalsFreezeXb::getFrozenType,"hour")
                .ge(ElectricityTerminalsFreezeXb::getFreezeTime,startDay)
                .le(ElectricityTerminalsFreezeXb::getFreezeTime,endDay));

        Map<String,Object> tempMap = new HashMap<>();
        List<Double> valueList = new ArrayList<>();
        //电表设备一天的小时数据
        Map<String,List<ElectricityTerminalsFreezeXb>> dataMap = freezeXbList.stream().collect(Collectors.groupingBy(ElectricityTerminalsFreezeXb::getFreezeTime));
        double total = 0;
        for (String hour : hourList) {
            double v = 0;
            if (dataMap.containsKey(date + " " + hour + ":00")) {
                List<ElectricityTerminalsFreezeXb> tempList = dataMap.get(date + " " + hour + ":00");
                v = tempList.get(0).getDosageCombinationActiveEnergy1().doubleValue();
            }
            valueList.add(v);
            total+=v;
        }
        tempMap.put("sum",total);
        tempMap.put("valueList",valueList);
        return tempMap;
    }

    /**
    * @Description: 获取小时冻结数据
    * @date: 2025/3/14 16:06
    * @author: zt
    */
    private List<Map<String,Object>> getYesterFreezeMap(Map<String,ElectricityTerminalsXb> locationNbMap,String date,List<String> hourList){
        String startDay = date + " 00:00:00";
        String endDay = date + " 23:59:59";
        List<String> locationNbList = new ArrayList<>(locationNbMap.keySet());
        //冻结小时数据
        List<ElectricityTerminalsFreezeXb> freezeXbList = this.getBaseMapper().selectList(new LambdaQueryWrapper<ElectricityTerminalsFreezeXb>()
                .in(ElectricityTerminalsFreezeXb::getLocationNb,locationNbList)
                .eq(ElectricityTerminalsFreezeXb::getFrozenType,"hour")
                .ge(ElectricityTerminalsFreezeXb::getFreezeTime,startDay)
                .le(ElectricityTerminalsFreezeXb::getFreezeTime,endDay));
        //根据locationNb分组
        Map<String,List<ElectricityTerminalsFreezeXb>> lnbDataMap = freezeXbList.stream().collect(Collectors.groupingBy(ElectricityTerminalsFreezeXb::getLocationNb));
        //所有设备统计数据生成数组
        List<Map<String,Object>> mapList = new ArrayList<>();
        for (String locationNb:lnbDataMap.keySet()){
            Map<String,Object> tempMap = new HashMap<>();
            List<Double> valueList = new ArrayList<>();
            String terminalName = locationNbMap.get(locationNb).getInstallAddress();
            tempMap.put("locationNb",locationNb);
            tempMap.put("terminalName",terminalName);
            //电表设备一天的小时数据
            List<ElectricityTerminalsFreezeXb> list = lnbDataMap.get(locationNb);
            Map<String,List<ElectricityTerminalsFreezeXb>> dataMap = list.stream().collect(Collectors.groupingBy(ElectricityTerminalsFreezeXb::getFreezeTime));
            double total = 0;
            for (String hour : hourList) {
                double v = 0;
                if (dataMap.containsKey(date + " " + hour + ":00")) {
                    List<ElectricityTerminalsFreezeXb> tempList = dataMap.get(date + " " + hour + ":00");
                    v = tempList.get(0).getDosageCombinationActiveEnergy1().doubleValue();
                }
                valueList.add(v);
                total+=v;
            }
            tempMap.put("sum",total);
            tempMap.put("valueList",valueList);
            mapList.add(tempMap);
        }
        mapList.sort(Comparator.comparing((Map<String, Object> m) -> (Double) m.get("sum")).reversed());
        return mapList;
    }

    private List<Long> recesiveAreaIds(List<MeterSheets> sheetsList){
        List<Long> areaIds = new ArrayList<>();
        for (MeterSheets sheet : sheetsList) {
            if (sheet.getChildren() != null && !sheet.getChildren().isEmpty()) {
                areaIds.addAll(recesiveAreaIds(sheet.getChildren()));
            } else {
                areaIds.add(sheet.getId());
            }
        }
        return areaIds;
    }
    /**
     * 用水量报表日、月报表
     * @param frozen_type
     * @param freezeTime
     * @return
     */
    @Override
    public int insertElectricityTerminalsFreezeXbForAll(String frozen_type, String freezeTime)
    {
        electricityTerminalsFreezeXbMapper.deleteElectricityTerminalsFreezeXbByType(frozen_type,freezeTime);
        if("day".equals(frozen_type)){
            List<ElectricityTerminalsFreezeXb> freezeXbList = electricityTerminalsFreezeXbMapper.selectDailyForInsertByDay(freezeTime);
            //electricityTerminalsFreezeXbMapper.insertByDay(freezeTime);
            if(freezeXbList.size()>0)
                electricityTerminalsFreezeXbMapper.insertBatch(freezeXbList);

        }else if("month".equals(frozen_type)){
            List<ElectricityTerminalsFreezeXb> freezeXbList = electricityTerminalsFreezeXbMapper.selectDailyForinsertByMonthForOne("1",freezeTime,"");
            if(freezeXbList.size()>0)
                electricityTerminalsFreezeXbMapper.insertBatch(freezeXbList);
        }
        return 1;
    }
    /**
     * 用户离场的设备用量（frequency_type：2、）、离场用户影响的公摊生产、消费用户（frequency_type：3）
     * @param frequencyType
     * @param freezeTime
     * @param userId
     * @return
     */
    @Override
    public int insertElectricityTerminalsFreezeXbForPhase(String frequencyType, String freezeTime, String userId,String departureTime)
    {

        if("2".equals(frequencyType)){//用户离场的设备用量
            List<ElectricityTerminalsFreezeXb> freezeXbList = electricityTerminalsFreezeXbMapper.selectDailyForinsertByMonthForTwo("2",freezeTime,userId);
            //return terminalsFreezeXbMapper.insertByDay(freezeTime);
            if(freezeXbList.size()>0)
                electricityTerminalsFreezeXbMapper.insertBatch(freezeXbList);
        }else if("3".equals(frequencyType)){//离场用户影响的公摊生产、消费用户
            List<ElectricityTerminalsFreezeXb> freezeXbList = electricityTerminalsFreezeXbMapper.selectDailyForinsertByMonthForThree("3",freezeTime,userId,departureTime);
            //return terminalsFreezeXbMapper.insertByMonth(freezeTime);
            if(freezeXbList.size()>0)
                electricityTerminalsFreezeXbMapper.insertBatch(freezeXbList);
        }
        return 1;
    }


    /**
     * @Description: 返回最下级区域
     * @date: 2025/3/14 13:23
     * @author: zt
     */
    public List<MeterSheets> recursiveLast(List<MeterSheets> sheetsList){
        List<MeterSheets> lastList = new ArrayList<>();
        for (MeterSheets sheet : sheetsList) {
            if (sheet.getChildren() != null && !sheet.getChildren().isEmpty()) {
                lastList.addAll(recursiveLast(sheet.getChildren()));
            } else {
                lastList.add(sheet);
            }
        }
        return lastList;
    }
}
